#include "../hdr/big_math.h"
#include <stdio.h>
#include <string.h>


void testInit() {
	char* numString = "678B6387-B7839AE8-238749BF-EC2A9F97-3768832B";
	big_int* testValue = (big_int*) malloc(sizeof(big_int));	
        printf("Expected number: %s\n", numString);
	init_big_int(testValue, numString);
	print_big_int(testValue);
	free(testValue);
}


void testAdd() {
	big_int* result = (big_int*) malloc(sizeof(big_int));
	big_int* op1 = (big_int*) malloc(sizeof(big_int));
	big_int* op2 = (big_int*) malloc(sizeof(big_int));

	init_big_int(op1, "FF000029-FFF00067");
	init_big_int(op2, "FF0000a3-FFF00082");

	add(result, op1, op2);

	printf("FF000029-FFF00067 + FF0000a3-FFF00082 = \n");
	print_big_int(result);

	free(result);
	free(op1);
	free(op2);
}

void test_bit_mult() {
	char* numString3 =  "678B6197-B7839AE8-238749BF-EC2A9F97-3768832B";

	big_int* testValue3 = (big_int*) malloc(sizeof(big_int));	

	init_big_int(testValue3, numString3);

	printf("Original Number:\n");
	print_big_int(testValue3);

	printf("multiplied by 1:");
	print_big_int(bit_mult(testValue3, 1));
	printf("multiplied by 0:");
	print_big_int(bit_mult(testValue3, 0));

	free(testValue3);
}

void test_bit_at() {
	char* numString4 = "67823487-B7839AE8-238749BF-EC2A9F97-3768832B";

	big_int* testValue4 = (big_int*) malloc(sizeof(big_int));	

	printf("Number:\n");
	print_big_int(testValue4);

	init_big_int(testValue4, numString4);

	printf("Expected: 0x0111\n");
	printf("bit at %d: %d\n", 24, bit_at(testValue4, 24));
	printf("bit at %d: %d\n", 25, bit_at(testValue4, 25));
	printf("bit at %d: %d\n", 26, bit_at(testValue4, 26));
	printf("bit at %d: %d\n", 27, bit_at(testValue4, 27));

	printf("Expected: 0x0100 \n");

	printf("bit at %d: %d\n", 80, bit_at(testValue4, 80));
	printf("bit at %d: %d\n", 81, bit_at(testValue4, 81));
	printf("bit at %d: %d\n", 82, bit_at(testValue4, 82));
	printf("bit at %d: %d\n", 83, bit_at(testValue4, 83));

	free(testValue4);
}

void test_right_shift() {
	char* numString = "B7839AE8-238749BF-EC2A9F97-3768832B";

	big_int* testValue5 = (big_int*) malloc(sizeof(big_int));	
	big_int* resultValue5 = (big_int*) malloc(sizeof(big_int));

	init_big_int(testValue5, numString);

	right_shift_by1(resultValue5, testValue5);

	printf("original number:");
	print_big_int(testValue5);
	printf("right shifted by 1:");
	print_big_int(resultValue5);

	free(testValue5);
	free(resultValue5);
}

void test_subtract() {
	big_int* result6 = (big_int*) malloc(sizeof(big_int));
	big_int* op16 = (big_int*) malloc(sizeof(big_int));
	big_int* op26 = (big_int*) malloc(sizeof(big_int));

	init_big_int(op16, "FF230029-EB340067");
	init_big_int(op26, "0F0000a3-FFF0D082");

	subtract(result6, op16, op26);

	printf("FF230029-EB340067 - 0F0000a3-FFF0D082 = \n");
	print_big_int(result6);

	free(result6);
	free(op16);
	free(op26);
}

void test_num_bits() {

	char* numString7 = "3e786a9-64789287-B7839AE8-238749BF-EC2A9F97-3768832B";

	big_int* testValue7 = (big_int*) malloc(sizeof(big_int));	

	init_big_int(testValue7, numString7);

	printf("Expected num bits: 186\n");
	printf("actual: %d\n", num_bits(testValue7));
	
	free(testValue7);
}


int main () {

	unsigned int op1 = 87;
	unsigned int op2 = 54;
	printf("87 - 54 = %u \n", (op1 - op2));
	printf("sizeof int: %d \n", sizeof(unsigned int));
	printf("sizeof long: %d \n", sizeof(unsigned long long int));

	lib_init();

	printf("Test init function: \n");
	testInit();

	printf("\n Test add function: \n");
	testAdd();

	printf("\n Test bit multiplication: \n");
	test_bit_mult();

	printf("\n Test bit retrieval: \n");
	test_bit_at();

	printf("\n Test right shift: \n");
	test_right_shift();
	
	printf("\n Test subtract: \n");
	test_subtract();

	printf("\n Test num bits: \n");
	test_num_bits();

	//printf("\n Test unsigned subtraction: \n");
	//unsigned int operand1 = 30;
	//printf("30 - 24 = %d\n", (operand1 - operand2));
}
